home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacHack 1996
/
MacHack 1996.toast
/
Hacks
/
Hacks ’87
/
Source ƒ.sit
/
Source ƒ
/
C ƒ
/
CITADEL BBS 'C' SRC
/
MISC.C
< prev
next >
Wrap
C/C++ Source or Header
|
1987-01-14
|
23KB
|
736 lines
/************************************************************************/
/* misc.c */
/* */
/* Random functions. */
/************************************************************************/
/************************************************************************/
/* history */
/* */
/* 86Aug19 HAW Kill history because of space problems. */
/* 84Jun10 JLS Function changedate() installed. */
/* 84May01 HAW Starting 1.50a upgrade. */
/* 83Mar12 CrT from msg.c */
/* 83Mar03 CrT & SB Various bug fixes... */
/* 83Feb27 CrT Save private mail for sender as well as recipient. */
/* 83Feb23 Various. transmitFile() won't drop first char on WC... */
/* 82Dec06 CrT 2.00 release. */
/* 82Nov05 CrT Stream retrieval. Handles messages longer than MAXTEXT.*/
/* 82Nov04 CrT Revised disk format implemented. */
/* 82Nov03 CrT Individual history begun. General cleanup. */
/************************************************************************/
#include "ctdl.h"
/************************************************************************/
/* contents */
/* */
/* changeDate() allow changing of date */
/* configure() sets terminal parameters via dialogue */
/* crashout() crashes out of Citadel in case of bug */
/* diskSpaceLeft() amount of space left on specified disk */
/* doCR() newline on modem and console */
/* download() menu-level routine for WC-protocol sends*/
/* getdate() gets date from MSDOS system clock. */
/* ingestFile() puts file in held message buffer */
/* patchDebug() display/patch byte */
/* printDate() prints out date */
/* putBufChar() .EWM/.EXM/.EWN/.EXN internal */
/* putFLChar() readFile() -> disk file interface */
/* setdate() sets the date */
/* transmitFile() send a host file, no formatting */
/* tutorial() first level for printing a help file */
/* upLoad() menu-level read-via-WC-protocol fn */
/* visible() convert control chars to letters */
/* writeTutorial() prints a .hlp file */
/************************************************************************/
/************************************************************************/
/* External variable declarations in MISC.C */
/************************************************************************/
static char *monthTab[13] = {"", "Jan", "Feb", "Mar",
"Apr", "May", "Jun",
"Jul", "Aug", "Sep",
"Oct", "Nov", "Dec" };
FILE *upfd;
int masterCount;
int acount;
int byteRate; /* Bytes/sec that modem is set for. */
char *NoFileStr = "\n No %s.\n";
char *who_str = "who";
char *strFile = "filename";
char *VERSION = "2.12";
char *ALL_LOCALS = "&L";
char *R_SH_MARK = "&&";
char *WRITE_LOCALS = "All Local Systems";
int fixVers = 128;
int majorVers = 34;
char *netVersion = "1.6";
#define AUDIT 9000
char audit[AUDIT];
/************************************************************************/
/* External variable definitions for MISC.C */
/************************************************************************/
extern struct config cfg; /* Lots an lots of variables */
extern struct logBuffer logBuf; /* Person buffer */
extern struct aRoom roomBuf; /* Room buffer */
extern struct rTable roomTab[];
extern struct msgB msgBuf;
extern struct msgB tempMess;
extern int outPut;
extern unsigned char termNulls; /* How many nulls? */
extern unsigned char termWidth; /* How many columns? */
extern char termUpper; /* Upper only? */
extern char termLF; /* Linefeeds? */
extern char onConsole;
extern char expert; /* expert? */
extern char aide; /* aide? */
extern char sendTime; /* Show time message created? */
extern unsigned char crtColumn; /* where are we on screen now? */
extern char loggedIn; /* Is we logged in? */
extern char *indexTable;
extern char outFlag; /* Output flag */
extern char haveCarrier; /* Do we still got carrier? */
extern char heldMess;
extern char usingWCprotocol;/* WC flag */
extern char prevChar; /* previous char output */
extern char textDownload; /* flag */
extern char whichIO; /* Where I/O is */
extern char echo; /* Should we echo? echo? echo? */
extern FILE *msgfl;
extern FILE *roomfl;
extern FILE *logfl;
extern char oldToo;
extern int exitValue;
/************************************************************************/
/* External function definitions for MISC.C */
/************************************************************************/
char mAbort();
long getNumber();
FILE *safeopen();
/*
* This function calculates the CRC used by the XMODEM/CRC Protocol
* The first argument is a pointer to the message block.
* The second argument is the number of bytes in the message block.
* The function returns an integer which contains the CRC.
* The low order 16 bits are the coefficients of the CRC.
* Taken from XYMODEM.DOC -- HAW.
*/
int calcrc(ptr, count)
char *ptr;
int count;
{
int crc, i;
crc = 0;
while (--count >= 0) {
crc = crc ^ (int)*ptr++ << 8;
for (i = 0; i < 8; ++i)
if (crc & 0x8000)
crc = crc << 1 ^ 0x1021;
else
crc = crc << 1;
}
return (crc & 0xFFFF);
}
/************************************************************************/
/* changedate() gets the date from the aide and remembers it */
/************************************************************************/
changeDate()
{
int year, day, hours, minutes;
char *month;
getdate(&year, &month, &day, &hours, &minutes);
mPrintf("Current date is: %d%s%02d\n ", year, month, day);
mPrintf("Current time is: %d:%02d\n ", hours, minutes);
if (!getYesNo("Enter a new date & time"))
return ;
setdate();
}
/************************************************************************/
/* configure() sets up terminal width etc via dialogue */
/************************************************************************/
configure(showVals)
char showVals;
{
if (showVals && loggedIn) {
mPrintf("\n Your current setup:\n ");
mPrintf("%s, ", (expert) ? "Expert" : "Non-expert");
mPrintf("%s,\n %slinefeeds, %d nulls,",
termUpper ? "UPPERCASE ONLY" : "Upper and Lower case",
termLF ? "" : "no ",
termNulls
);
mPrintf(" screen width is %d\n ", termWidth);
mPrintf("%s time messages created,\n ",
sendTime ? "Print" : "Do not print");
mPrintf("%s last Old message on <N>ew Message request.",
oldToo ? "Print" : "Do not print");
mPrintf("\n ");
if (!getYesNo("Reset your configuration")) return;
}
mPrintf("\n ");
termWidth = (int) getNumber(" Screen width", 10l, 255l);
termNulls = (int) getNumber(" #Nulls (normally 0)", 0l, 255l);
termUpper =!getYesNo(" Do you have lower case" ) ? TRUE : FALSE;
termLF = getYesNo(" Do you need Linefeeds" ) ? TRUE : FALSE;
expert = getYesNo(" Are you an experienced Citadel user")
? TRUE : FALSE;
sendTime = getYesNo(" Print time messages created") ? TRUE : FALSE;
if (expert)
oldToo = getYesNo(" Print last Old message on <N>ew Message request")
? TRUE : FALSE;
else oldToo = FALSE;
/* Now make it (only) semi-permanent --JLS&HAW */
logBuf.lbwidth = termWidth;
logBuf.lbnulls = termNulls;
logBuf.lbflags.EXPERT = expert;
logBuf.lbflags.UCMASK = termUpper;
logBuf.lbflags.LFMASK = termLF;
logBuf.lbflags.AIDE = aide;
logBuf.lbflags.TIME = sendTime;
logBuf.lbflags.OLDTOO = oldToo;
}
/************************************************************************/
/* crashout() Problems? Out we go!!! */
/************************************************************************/
crashout(message)
char *message;
{
extern char IBMinterrupts;
FILE *fd; /* Record some crash data */
int i;
exitValue = CRASH_EXIT;
outFlag = IMPERVIOUS;
mPrintf("\n Whoops!! CRASHOLA!! Thanks and bye, leave mail on Test Sys!\n ");
printf("STATUS:\nmsgfl %d\nlogfl %d\nroomfl %d\n",
ferror(msgfl), ferror(logfl), ferror(roomfl));
interpret(cfg.pHangUp);
fclose(msgfl);
fclose(roomfl);
fclose(logfl);
fd = safeopen("crash", "w");
fprintf(fd, message);
fclose(fd);
fd = safeopen("audit", "w");
for (i = 0; i < AUDIT; i++) {
fputc(audit[i], fd);
if ((i+1) % 70 == 0) fprintf(fd, "\n");
}
fprintf(fd, "\n\ncounter = %d\n", acount);
fclose(fd);
writeSysTab();
modemClose();
exit(exitValue);
}
/************************************************************************/
/* diskSpaceLeft() Amount of space left on specified disk */
/************************************************************************/
diskSpaceLeft(drive, sectors, bytes)
char drive;
long *bytes;
long *sectors;
{
struct regval s;
long temp;
s.ax = 0x3600;
s.dx = toUpper(drive) - 'A' + 1;
sysint21(&s, &s);
if (s.ax == 0xffff) return FALSE;
temp = s.ax;
*bytes = temp * s.bx * s.cx;
*sectors = ((*bytes) + 127) / SECTSIZE;
return TRUE;
}
/************************************************************************/
/* doCR() does a newline on modem and console */
/************************************************************************/
doCR()
{
int i;
crtColumn = 1;
if (outFlag != OUTOK && /* output is being s(kip)ped */
outFlag != IMPERVIOUS)
return;
if (outPut == DISK) fprintf(upfd, "\n");
else {
if (usingWCprotocol == WC_NONE)
mputChar(NEWLINE);
if (haveCarrier) {
if (usingWCprotocol == WC_NONE) {
outMod('\r');
for (i = termNulls; i; i--) outMod(0);
if (termLF) outMod('\n');
} else {
sendWCChar('\r');
if (termLF) sendWCChar('\n');
}
}
}
prevChar = ' ';
}
/************************************************************************/
/* download() is the menu-level send-message-via-WC-protocol fn */
/************************************************************************/
download(whichMess, revOrder, whatkind)
char whichMess, revOrder, whatkind;
{
outFlag = OUTOK;
if (!expert) tutorial("wcdown.blb");
if (!getYesNo("Ready")) return;
/* here we go: */
echo = NEITHER;
usingWCprotocol = whatkind; /* all points bulletin */
if (doWC(STARTUP)) {
if (whichMess != GLOBALnEW)
showMessages(whichMess, revOrder);
else
doGlobal(revOrder);
doWC(FINISH);
}
setUp(FALSE);
usingWCprotocol = WC_NONE;
}
/************************************************************************/
/* doGlobal() Does .R{W,X}G */
/************************************************************************/
doGlobal(revOrder)
char revOrder;
{
while (outFlag != OUTSKIP && gotoRoom("", 'R')) {
givePrompt();
mPrintf("read new\n ");
showMessages(NEWoNLY, revOrder);
}
}
/************************************************************************/
/* formRoom() returns a string with the room formatted */
/************************************************************************/
char *formRoom(roomNo, showPriv)
int roomNo, showPriv;
{
static char display[40];
int one, two;
static char matrix[2][2] =
{ { '>', ')' } ,
{ ']', ':' } } ;
one = roomTab[roomNo].rtflags.MSDOSDIR;
two = roomTab[roomNo].rtflags.SHARED;
if (roomTab[roomNo].rtflags.INUSE) {
sPrintf(display, "%s%c%s",
roomTab[roomNo].rtname,
matrix[one][two],
(!roomTab[roomNo].rtflags.PUBLIC && showPriv) ? "*" : "");
}
else display[0] = '\0';
return display;
}
/************************************************************************/
/* getdate() retrieves system date and returns in the parameters */
/************************************************************************/
getdate(year, month, day, hours, minutes)
int *year, *day, *hours, *minutes;
char **month;
{
#ifdef MSDOS
struct regval s;
s.ax = 0x2a00;
sysint21(&s, &s);
*year = s.cx - 1900;
*month = monthTab[(s.dx & 0xff00) >> 8];
*day = (s.dx & 0x00ff);
s.ax = 0x2c00;
sysint21(&s, &s);
*hours = (s.cx & 0xff00) >> 8;
*minutes = s.cx & 0x00ff;
#else
*year = interpret(pGetYear);
*month = interpret(pGetMonth);
*day = interpret(pGetDay);
*hours = *minutes = 0;
#endif
}
/************************************************************************/
/* ingestFile() Puts the given file in the held msg buffer */
/************************************************************************/
ingestFile()
{
char filename[100]; /* Paths, etc.... */
FILE *fd;
int getc(), c, index;
getNormStr(strFile, filename, 99, ECHO);
if ((fd = safeopen(filename, "r")) == NULL) {
mPrintf(NoFileStr, filename);
return;
}
index = (heldMess) ? strLen(tempMess.mbtext) : 0;
while ((c = getc(fd)) != EOF && index < MAXTEXT - 2) {
if (c) tempMess.mbtext[index++] = c;
}
tempMess.mbtext[index] = 0;
fclose(fd);
heldMess = TRUE;
}
/************************************************************************/
/* printDate() prints out current date. */
/************************************************************************/
printDate()
{
int day, year, h, m;
char *month;
getdate(&year, &month, &day, &h, &m);
mPrintf("%d%s%02d ", year, month, day);
}
/************************************************************************/
/* putBufChar() is used to upload messages via WC */
/* returns: ERROR on problems else TRUE */
/************************************************************************/
putBufChar(c)
int c;
{
char result;
static char ourFilter[] =
/* 0 */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, ' ',
/* 10 */ '\n', 0, 0, '\n', 0, 0, 0, 0, 0, 0,
/* 20 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 30 */ 0, 0, ' ', '!', '"', '#', '$', '%', '&', '\'',
/* 40 */ '(', ')', '*', '+', ',', '-', '.', '/', '0', '1',
/* 50 */ '2', '3', '4', '5', '6', '7', '8', '9', ':', ';',
/* 60 */ '<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E',
/* 70 */ 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
/* 80 */ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y',
/* 90 */ 'Z', '[', '\\', ']', '^', '_', '`', 'a', 'b', 'c',
/* 100 */ 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
/* 110 */ 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
/* 120 */ 'x', 'y', 'z', '{', '!', '}', '~', 0 };
if (masterCount > MAXTEXT - 2) return ERROR;
c &= 0x7F; /* strip high bit */
result = cfg.filter[c];
if (result == '\0') {
return TRUE;
}
msgBuf.mbtext[masterCount++] = result;
msgBuf.mbtext[masterCount] = 0; /* EOL just for luck */
return TRUE;
}
/************************************************************************/
/* putFLChar() is used to upload files */
/* returns: ERROR on problems else TRUE */
/************************************************************************/
putFLChar(c)
char c;
{
if (fputc(c, upfd) != EOF) return TRUE;
/* else */ printf("Write error: %d\n", ferror(upfd));
return ERROR;
}
/************************************************************************/
/* setdate() Sets the date. */
/************************************************************************/
setdate()
{
#ifdef MSDOS
struct regval s;
while (1) {
s.cx = (int) getNumber("Year", 85l, 99l) + 1900;
s.dx = (int) getNumber("Month", 1l, 12l) << 8 ;
s.dx += (int) getNumber("Day", 1l, 31l) ;
s.ax = 0x2b00;
sysint21(&s, &s);
if (s.ax & 0xff)
mPrintf("Invalid date\n ");
else
break;
}
while (1) {
s.cx = (int) getNumber("Hour", 0l, 23l) << 8;
s.cx += (int) getNumber("Minute", 0l, 59l) ;
s.dx = 0;
s.ax = 0x2d00;
sysint21(&s, &s);
if (s.ax & 0xff)
mPrintf("Invalid time\n ");
else
break;
}
#else
interpret(pInitDate);
#endif
}
/************************************************************************/
/* systemCommands() Some MS-DOS commands */
/************************************************************************/
systemCommands()
{
int errorCode;
char filename[200];
while (onLine()) {
outFlag = OUTOK;
mPrintf("\n System commands: ");
switch (toUpper(iChar())) {
case 'X':
mPrintf("\bExit from System Commands menu\n ");
return ;
case 'D':
mPrintf("elete file\n ");
getNormStr(strFile, filename, 199, ECHO);
doCR();
mPrintf("File %s.\n ", (unlink(filename) == 0) ?
"deleted" : "not found");
break;
case 'O':
mPrintf("utside commands\n One moment, please.");
writeSysTab();
getString("command line", filename, 198, FALSE, ECHO);
if ((errorCode = system(filename)) != 0) {
mPrintf("FAILED: ");
switch (errorCode) { /* See the C-86 manual for this */
case 1: mPrintf("VeryBadUnknownError\n "); break;
case 2: mPrintf("Command.com not found\n "); break;
case 5: mPrintf("Access denied\n "); break;
case 8: mPrintf("Insufficient memory\n "); break;
case 10: mPrintf("Bad environment\n "); break;
default: mPrintf("Bad return Value\n "); break;
}
}
unlink(indexTable);
break;
case '?':
tutorial("sysopt.mnu");
break;
default:
if (!expert) mPrintf(" ?(Type '?' for menu)\n " );
else mPrintf(" ?\n " );
break;
}
}
}
/************************************************************************/
/* transmitFile() dumps a host file with no formatting */
/************************************************************************/
transmitFile(filename)
char *filename;
{
#define CPMEOF 26 /* For CP/M files, EOF == ^Z */
int getc(), sendWCChar();
long fseek(), totalSectors, fileSize;
long Secs, Mins, totalTime, totalBytes;
char protocol;
FILE *fbuf;
int c;
outFlag = OUTOK;
if ((fbuf = safeopen(filename, "rb")) == NULL) {
usingWCprotocol = WC_NONE;
mPrintf(NoFileStr, filename);
return(ERROR);
}
doCR();
if (usingWCprotocol != WC_NONE) {
protocol = usingWCprotocol;
usingWCprotocol = FALSE;
if (byteRate != 0) {
fileSize = fseek(fbuf, -1l, 2) + 1;
rewind(fbuf);
totalSectors = ((fileSize + SECTSIZE - 1) / SECTSIZE);
#ifdef OLDCALCS
if (byteRate == 30)
totalTime = (totalSectors * 9) / 2;
else if (byteRate == 120)
totalTime = (totalSectors * 3) / 2;
else if (byteRate == 240) /* Best guess */
totalTime = (totalSectors * 3) / 4;
#else
if (byteRate == 30)
totalTime = (totalSectors * 10);
else if (byteRate == 120)
totalTime = (totalSectors * 5) / 4;
else if (byteRate == 240) /* Best guess */
totalTime = (totalSectors * 5) / 8;
#endif
Mins = totalTime / 60;
Secs = totalTime % 60;
mPrintf("\n Total time to download '%s' should be about ",filename);
if (Mins != 0l)
mPrintf("%ld minute%s, ", Mins,
(Mins == 1l) ? "" : "s");
mPrintf("%2ld second%s (%ld blocks).",
Secs, (Secs == 1l) ? "" : "s", totalSectors);
}
if (!getYesNo("Ready for WC transfer")) {
fclose(fbuf);
return ERROR;
}
usingWCprotocol = protocol;
sendWCFile(fbuf);
usingWCprotocol = WC_NONE;
oChar(BELL);
return ;
}
while ((c = getc(fbuf)) != ERROR && (c != CPMEOF || !textDownload)) {
mputChar(c);
if (interpret(cfg.pCarrDetect)) outMod(c);
if (mAbort() || (whichIO == MODEM && !gotCarrier())) break;
}
fclose(fbuf);
}
/************************************************************************/
/* tutorial() prints file <filename> on the modem & console */
/* Returns: TRUE on success else ERROR */
/************************************************************************/
#define MAXWORD 256
tutorial(filename)
char *filename;
{
FILE *fbuf;
char line[MAXWORD];
int toReturn;
toReturn = TRUE;
outFlag = OUTOK;
if (filename[1] == ':' || (fbuf = safeopen(filename, "r")) == NULL) {
mPrintf(NoFileStr, filename);
toReturn = ERROR;
} else {
writeTutorial(fbuf, TRUE);
fclose(fbuf);
}
return toReturn;
}
/************************************************************************/
/* upLoad() enters a file into current directory */
/************************************************************************/
upLoad()
{
char fileName[NAMESIZE], *s;
int putFLChar();
char successful;
getNormStr(strFile, fileName, NAMESIZE, ECHO);
if (fileName[1] != ':') s = &fileName[0];
else s = &fileName[2];
if (!setSpace(roomBuf.rbdisk, roomBuf.rbdirname)) {
crashout("ERROR: DIRECTORY NOT FOUND!");
}
if ((upfd = safeopen(s, "r")) != NULL) {
mPrintf("\n A %s already exists.\n", s);
fclose(upfd);
} else {
if (!expert) {
if (strLen(roomBuf.rbdirname) != 0) setSpace(roomBuf.rbdisk, "..");
setSpace(cfg.homeDisk, "");
tutorial("wcupload.blb");
setSpace(roomBuf.rbdisk, roomBuf.rbdirname);
}
if ((upfd = safeopen(s, "wb")) == NULL) {
mPrintf("\n Can't create %s!\n", s);
} else {
if (!getYesNo("Ready for WC transfer"))
successful = FALSE;
else
successful = readFile(putFLChar);
fclose(upfd);
if (!successful) unlink(s);
else {
sPrintf(msgBuf.mbtext, "File \"%s\" uploaded into %s by %s.",
s, roomBuf.rbname, logBuf.lbname);
aideMessage(FALSE);
putMessage(FALSE); /* Now save message in this room*/
noteMessage(NULL, ERROR);
noteRoom();
}
}
}
if (strLen(roomBuf.rbdirname) != 0) setSpace(roomBuf.rbdisk, "..");
setSpace(cfg.homeDisk, "");
}
/************************************************************************/
/* visible() converts given char to printable form if nonprinting */
/************************************************************************/
char visible(c)
unsigned char c;
{
if (c==0xFF) c = '$' ; /* start-of-message in message.buf */
c = c & 0x7F ; /* kill high bit otherwise */
if ( c < ' ') c = c + 'A' -1; /* make all control chars letters */
if (c== 0x7F) c = '~' ; /* catch DELETE too */
return(c);
}
/************************************************************************/
/* writeTutorial() given a file, prints it */
/************************************************************************/
writeTutorial(fd, noviceWarning)
FILE *fd;
char noviceWarning;
{
char line[MAXWORD];
rewind(fd);
outFlag = OUTOK;
if (!expert && noviceWarning) mPrintf("\n <J>ump <P>ause <S>top\n");
mPrintf(" \n");
while (fgets(line, MAXWORD, fd)) mPrintf("%s", line);
}